package com.falcon.controller.toolkit;

import cn.hutool.core.util.RandomUtil;
import com.falcon.core.utils.BeanUtils;
import com.falcon.mvc.base.IBaseController;
import com.falcon.mvc.domain.BasePager;
import com.falcon.mvc.domain.BaseResponse;
import com.falcon.domain.dos.DemoDO;
import com.falcon.domain.dos.DemoTreeDO;
import com.falcon.domain.req.DemoQuery;
import com.falcon.domain.req.DemoRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/*
协议:
    * PostForm: 只有get请求
    * PostJson: 除Get请求之外的所有请求, Put/Post/Delete
参数类型:
    * PostJson:
        * 无参:
        * 单个路径参数:  /{id}
        * 自定义对象类型: DemoRequest
        * 自定义对象列表: List<DemoRequest>
        * 单路径参数 + 对象: /{id}, DemoRequest
        * 基本类型数组: List<Integer>, List<String>
    * postForm:
        * 单基本类型: String
        * 多基本类型: String, Integer. 超过两个要考虑封装为对象
        * 基本类型列表: List<String>, List<Integer>
        * 单自定义类型: DemoQuery
响应类型:
    * 基本类型: Long, Boolean
    * 基本类型列表: List<Long>
    * 自定义类型: DemoPO
    * 自定义类型列表: List<DemoPO>
    * 分页类型: Pager<DemoPO>
    * 树列表: List<DemoTreeDO>
 */

@Slf4j
@RestController
@RequestMapping("/toolkit/demo")
@Tag(name = "DemoController", description = "Controller 示例")
public class DemoController implements IBaseController {

    @Operation(summary = "json协议: 只有body参数", description = "响应类型: 基本类型")
    @PostMapping("/jsonBody")
    public BaseResponse<Long> jsonBody(@Valid @RequestBody DemoRequest request) {
        return BaseResponse.success(request.getId());
    }

    @Operation(summary = "json协议: 只有路径参数，无body参数 ", description = "响应类型: 基本类型")
    @DeleteMapping("/jsonPath/{id}")
    public BaseResponse<Boolean> jsonPath(@PathVariable Long id) {
        return BaseResponse.success(true);
    }

    @Operation(summary = "json协议: 路径参数 + body参数 ", description = "响应类型: 基本类型")
    @PutMapping("/jsonBodyAndPath/{id}")
    public BaseResponse<String> jsonBodyAndPath(@PathVariable Long id, @Valid @RequestBody DemoRequest request) {
        return BaseResponse.success(request.toString());
    }

    @Operation(summary = "json协议: body为基本类型数组", description = "响应类型: 基本类型")
    @PostMapping("/jsonBasicList")
    public BaseResponse<String> jsonBasicList(@RequestBody List<Long> ids) {
        return BaseResponse.success(ids.toString());
    }

    @Operation(summary = "json协议: body为对象类型数组", description = "响应类型: 基本类型列表")
    @PostMapping("/jsonObjectList")
    public BaseResponse<List<Long>> jsonObjectList(@RequestBody List<DemoRequest> requests) {
        List<Long> idList = requests.stream().map(DemoRequest::getId).collect(Collectors.toList());
        return BaseResponse.success(idList);
    }

    @Operation(summary = "json协议: 无参", description = "响应类型: List自定义类型")
    @PostMapping("/jsonNoBody")
    public BaseResponse<List<DemoDO>> jsonNoBody() {
        return BaseResponse.success(getDemoList());
    }

    @Operation(summary = "分页查询", description = "响应类型: 自定义类型分页")
    @PostMapping("/jsonPager")
    public BaseResponse<BasePager<DemoDO>> jsonPager(@RequestBody DemoQuery request) {
        BasePager<DemoDO> pager = new BasePager<>();
        pager.setPages(10);
        pager.setTotal(100);
        pager.setItems(getDemoList());
        pager.getItems().forEach(item -> item.setName(request.getName() + "-" + item.getName()));
        return BaseResponse.success(pager);
    }

    @Operation(summary = "form协议: 基本类型单参数", description = "响应类型: 自定义类型")
    @PostMapping("/formBasic")
    public BaseResponse<DemoDO> formBasic(String name) {
        DemoDO demoDO = getDemoList().get(0);
        demoDO.setName(name);
        return BaseResponse.success(demoDO);
    }

    @Operation(summary = "form协议: 基本类型多参数", description = "响应类型: 自定义类型列表")
    @PostMapping("/formMultiBasic")
    public BaseResponse<DemoDO> formMultiBasic(String name, Long id) {
        DemoDO demoDO = getDemoList().get(0);
        demoDO.setName(name);
        demoDO.setId(id);
        return BaseResponse.success(demoDO);
    }

    @Operation(summary = "form协议: 对象类型单参数", description = "响应类型: 自定义树")
    @PostMapping("/formObject")
    public BaseResponse<List<DemoTreeDO>> formObject(DemoQuery request) {
        List<DemoTreeDO> treeList = new ArrayList<>();
        for (DemoDO demoDO : getDemoList()) {
            DemoTreeDO demoTreeDO = BeanUtils.copyProperties(demoDO, DemoTreeDO.class);
            demoTreeDO.setName(request.getName());
            demoTreeDO.setChildren(BeanUtils.copyToList(getDemoList(5), DemoTreeDO.class));
            treeList.add(demoTreeDO);
        }
        return BaseResponse.success(treeList);
    }

    private List<DemoDO> getDemoList(Integer... length){
        int size = length.length == 0 ? 10: length[0];
        List<DemoDO> list = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            DemoDO demoDO = new DemoDO().setId(Long.valueOf((i+1)*RandomUtil.randomInt(20))).setName(RandomUtil.randomString(5)).setMan(i % 2 == 0).setCreateTime(new Date());
            list.add(demoDO);
        }
        Collections.sort(list, Comparator.comparing(DemoDO::getId));
        return list;
    }

}
